昨天介紹完Native App 今天會更詳細的說什麼是Native code
Native code 基本上是指 專門跑在特定的處理器架構上編譯過的程式碼, Android Studio 可以透過NDK(Native Development Kit )來對撰寫部分APP程式 透過C/C++ 程式碼
Native Code 主要會在 Shared Libraries .so 檔裡面. 這些library 可以被APP 透過 JNI (java native interface)使用 JNI 會幫忙過語言的function呼叫與資料傳遞
在Andorid Studion 可以透過 New Project -> Native C++ 建立專案 起來觀察
可以翻一下 /app/cpp 下 會有一個 native-lib.cpp 的檔案
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_studionativec1_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
Java_com_example_studionativec1_MainActivity_stringFromJNI 根據JNI取名慣例
這個function會被 MainActivity呼叫 在執行完function 會return 一個 String 回java 程式碼中
在java 中 要用Native的function 需要 先load 把 Native lib 加載進來
靜態加載function: System.load()
static {
System.loadLibrary("myapplication");
}
public native String stringFromJNI();
message.setText(stringFromJNI());
CMakeList.txt 用來描述 專案中Native file 資訊
觀察以下code nativ-lib.cpp 主要用在 studionativec1 這個APP
App/cpp/CMakeLists.txt
project("studionativec1")
add_library(${CMAKE_PROJECT_NAME} SHARED
# List C/C++ source files with relative paths to this CMakeLists.txt.
native-lib.cpp)
動態加載function: System.load()
Library 不只能靜態預先加載 也可以先在Runtime是加載 .so file
下面是一段 從本地/Download 複製.so 檔到APP 家目錄 並動態加載
try {
inputStream = new FileInputStream(new File(path_sd_card + "/Download/libupgrade.so"));
outputStream = new FileOutputStream(new File(filesDir + "/libupgrade.so"));
FileChannel inChannel = inputStream.getChannel();
FileChannel outChannel = outputStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
System.load(filesDir + "/libupgrade.so")
// Returns the value of the function stringFromJNI() from the libupgrade.so file
return stringFromJNI();
這裡 System.load(filesDir + "/libupgrade.so") 是不好的寫法 缺乏對檔案來源和完整性的驗證。